package cn.itcast.web.controller;

import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.User;
import cn.itcast.service.cargo.ContractService;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.UserService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
public class LoginController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private ModuleService moduleService;

    @Reference
    private ContractService contractService;

    /*
        作用：用户登陆
        url: /login.do
        参数： email,password
     */
    @RequestMapping("/login")
    public String login(String email,String password){
        //1. 判断邮箱与密码是否为空，如果为空则跳回到登录页面
        if(StringUtils.isEmpty(email)|| StringUtils.isEmpty(password)){
            request.setAttribute("error","用户名或者密码不能为空!");
            //如果返回值不需要经过视图解析器，需要使用redirect或者forward开头
            return "forward:/login.jsp";
        }

        try {
            //2. 得到subject对象
            Subject subject = SecurityUtils.getSubject();
            //3. 把邮箱与密码封装到一个Token
            UsernamePasswordToken token = new UsernamePasswordToken(email,password);

            //4. subject发出认证请求
            subject.login(token);

            //5.登录成功会 返回一个登陆成功对象,shiro在你登陆成功之后会往session中做登陆成功标记
            User loginUser = (User) subject.getPrincipal();
            //这里的session的数据只是为了让我们方便使用登陆者的信息而已，并不是登录成功标记
            session.setAttribute("loginUser",loginUser);
            //一旦该用户登陆成功之后，马上就应该查找该用户对应的权限
            List<Module> moduleList = moduleService.findModuleByUser(loginUser);
            session.setAttribute("modules",moduleList);


            //无论此登陆者是否为审核人都去审核一下手中的报运单
            contractService.access(loginUser);

            return "home/main";
        } catch (UnknownAccountException e) {
           //如果用户名不存在则抛出UnknownAccountException
            request.setAttribute("error","用户名不存在或者密码错误!");
            return "forward:/login.jsp";
        }catch (IncorrectCredentialsException e){
            //如果用户名不存在则抛出UnknownAccountException
            request.setAttribute("error","用户名不存在或者密码错误!");
            return "forward:/login.jsp";
        }
    }


    /*
          作用：用户注销

          注销的方案：
            1. 把session的登陆成功标记删除 session.removeAttribute("loginUser")
            2. 摧毁整个session
    */
    @RequestMapping("/logout")
    public String logout(){
        //1. 销毁shiro登陆成功标记
        Subject subject = SecurityUtils.getSubject();
        subject.logout(); //这个方法的作用销毁shiro登陆成功标记
        session.invalidate();
        //请求重定向: 会报错的   请求转发是没问题
        return "redirect:/login.jsp";  //请求重定向的时候会经过shiro的过滤器，shiro的过滤器由于不知道你已经是注销了，所以shiro的过滤器还是从session中获取登陆的标记信息
    }

    /*
       作用：加载home/home页面进内容区域
    */
    @RequestMapping("/home")
    public String home(){
        return "home/home";
    }
}
